package com.hna.iot.common.utils;

import org.apache.commons.io.IOUtils;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Htt网络工具包
 * 
 * @author wangdesen
 *
 */
public class HttpRequestUtils {

	protected static final transient Logger LOGGER = LoggerFactory.getLogger(HttpRequestUtils.class);

	private static final ThreadLocal<HttpResponse> HTTPRESPONSETHREADLOCAL = new ThreadLocal<HttpResponse>();

	public static PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();

	static {
		manager.setMaxTotal(2000);
		manager.setDefaultMaxPerRoute(800);
	}

	public static HttpClient HTTP_CLIENT = HttpClients.custom().setConnectionManager(manager).build();

	
	/**
	 * POST传输JOSN-String
	 * 
	 * @param url
	 * @param requestData
	 * @return
	 * @throws IOException
	 */
	public final static String sendHttpRequestForm(String url, String requestData) throws IOException {
		
		StringEntity strEntity = new StringEntity(requestData, "UTF-8");
		return sendHttpRequestForm(url, strEntity);
	}

	
	/**
	 * POST传输Stream
	 * 
	 * @param url
	 * @param requestData
	 * @return
	 * @throws IOException
	 */
	public final static String sendHttpRequestStream(String url, String requestData) throws IOException {
		
		HttpEntity entity = null;
		String responseData = null;
		try {
			HttpPost httpPost = new HttpPost(url);
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(15000)
					.setConnectionRequestTimeout(60000).build();
			httpPost.setConfig(requestConfig);
			LOGGER.debug("requestData:" + requestData); // 打印结果页面
			// 封装请求内容
			httpPost.addHeader("Content-type", "text/plain; charset=UTF-8");
			StringEntity strEntity = new StringEntity(requestData, "UTF-8");
			strEntity.setContentType("text/plain; charset=UTF-8");
			// 设置请求内容
			httpPost.setEntity(strEntity);

			// 发送请求
			HttpResponse response = HTTP_CLIENT.execute(httpPost);
			// 请求成功结果处理
			LOGGER.debug("StatusLine:{}", response.getStatusLine()); // 打印结果页面
			entity = response.getEntity();
			InputStream is = entity.getContent();
			Header encodingHeader = entity.getContentEncoding();
			Charset contentEncoding = encodingHeader == null ? Consts.UTF_8
					: Charset.forName(encodingHeader.getValue());

			BufferedReader reader = new BufferedReader(new InputStreamReader(is, contentEncoding));
			responseData = IOUtils.toString(reader);
			LOGGER.debug("responseData:{}", responseData); // 打印结果页面
		} finally {
			EntityUtils.consume(entity);
		}
		return responseData;
	}

	
	/**
	 * POST传输JSON-Form表单
	 * 
	 * @param url
	 * @param requestData
	 * @return
	 * @throws IOException
	 */
	public final static String sendHttpRequestForm(String url, Map<String, String> requestData) throws IOException {
		
		LOGGER.info("requestData:{}", requestData);
		// 封装请求内容
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		for (Map.Entry<String, String> entity : requestData.entrySet()) {
			params.add(new BasicNameValuePair(entity.getKey(), entity.getValue()));
		}
		HttpEntity formEntity = new UrlEncodedFormEntity(params, Consts.UTF_8);
		return sendHttpRequestForm(url, formEntity);
	}

	
	private final static String sendHttpRequestForm(String url, HttpEntity formEntity) throws IOException {
		// 使用http post方法请求
		// 获取应答数据
		HttpEntity entity = null;
		String responseData = null;
		try {
			HttpPost httpPost = new HttpPost(url);
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(15000)
					.setConnectionRequestTimeout(60000).build();
			httpPost.setConfig(requestConfig);
			httpPost.addHeader("Content-type","application/x-www-form-urlencoded;charset=UTF-8");
			// 设置请求内容
			httpPost.setEntity(formEntity);

			// 发送请求
			HttpResponse response = HTTP_CLIENT.execute(httpPost);
			// 请求成功结果处理
			LOGGER.debug("StatusLine:" + response.getStatusLine()); // 打印结果页面
			entity = response.getEntity();
			InputStream is = entity.getContent();
			Header encodingHeader = entity.getContentEncoding();
			Charset contentEncoding = encodingHeader == null ? Consts.UTF_8
					: Charset.forName(encodingHeader.getValue());

			BufferedReader reader = new BufferedReader(new InputStreamReader(is, contentEncoding));
			responseData = IOUtils.toString(reader);
			LOGGER.debug("responseData:{}", responseData); // 打印结果页面
		} finally {
			EntityUtils.consume(entity);
		}
		return responseData;
	}

	
	/**
	 * POST发送JSON-String
	 * 
	 * @param url
	 * @param requestData
	 * @return
	 * @throws Exception
	 */
	public final static String sendHttpRequestJson(String url, String requestData) throws Exception {
		// 使用http post方法请求
		HttpEntity entity = null;
		String responseData = null;
		try {
			HttpPost httpPost = new HttpPost(url);
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(15000)
					.setConnectionRequestTimeout(60000).build();
			httpPost.setConfig(requestConfig);
			LOGGER.debug("requestData:" + requestData); // 打印结果页面
			// 封装请求内容
			// httpPost.addHeader("Content-type", "application/json; charset=UTF-8");
			StringEntity strEntity = new StringEntity(requestData, "UTF-8");
			// 设置请求内容
			httpPost.setEntity(strEntity);

			HttpResponse response = null;
			entity = null;
			responseData = null;
			// 发送请求
			response = HTTP_CLIENT.execute(httpPost);

			// royleexh 2015年7月9日 10:28:08 将应答放入
			HTTPRESPONSETHREADLOCAL.set(response);

			// 请求成功结果处理
			LOGGER.debug("StatusLine:{}", response.getStatusLine()); // 打印结果页面
			// 获取应答数据
			entity = response.getEntity();
			InputStream is = entity.getContent();
			Header encodingHeader = entity.getContentEncoding();
			Charset contentEncoding = encodingHeader == null ? Consts.UTF_8
					: Charset.forName(encodingHeader.getValue());

			BufferedReader reader = new BufferedReader(new InputStreamReader(is, contentEncoding));
			responseData = IOUtils.toString(reader);
			LOGGER.debug("responseData:{}", responseData); // 打印结果页面
		} finally {
			EntityUtils.consume(entity);
		}
		return responseData;
	}

	
	/**
	 * get方式请求
	 * 
	 * @param url
	 * @return
	 * @throws IOException
	 */
	public final static String get(String url) throws IOException {
		// 获取应答数据
		HttpEntity entity = null;
		String responseData = null;
		try {
			LOGGER.debug("requestData:{}", url);
			// 使用http post方法请求
			HttpGet httpGet = new HttpGet(url);
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(30000)
					.setConnectionRequestTimeout(60000).build();
			httpGet.setConfig(requestConfig);
			// 发送请求
			HttpResponse response = HTTP_CLIENT.execute(httpGet);

			// 请求成功结果处理
			LOGGER.debug("StatusLine:" + response.getStatusLine()); // 打印结果页面
			entity = response.getEntity();
			InputStream is = entity.getContent();
			Header encodingHeader = entity.getContentEncoding();
			Charset contentEncoding = encodingHeader == null ? Consts.UTF_8
					: Charset.forName(encodingHeader.getValue());

			BufferedReader reader = new BufferedReader(new InputStreamReader(is, contentEncoding));
			responseData = IOUtils.toString(reader);
			LOGGER.debug("responseData:{}", responseData); // 打印结果页面
		} catch (IllegalStateException e) {
			LOGGER.error("测试一卡通前置地址失败", e);
		} finally {
			EntityUtils.consume(entity);
		}
		return responseData;
	}

	
	/**
	 * 下载文件
	 * 
	 * @param url
	 * @param file
	 * @throws Exception
	 */
	public static void downLoad(String url, File file) throws Exception {
		HttpGet httpGet = new HttpGet(url);
		HttpResponse httpResponse = HTTP_CLIENT.execute(httpGet);
		HttpEntity entity = httpResponse.getEntity();
		InputStream in = entity.getContent();
		OutputStream out = new FileOutputStream(file);
		saveTo(in, out);
	}

	
	/**
	 * 存储输出流
	 * 
	 * @param in
	 * @param out
	 * @throws Exception
	 */
	public static void saveTo(InputStream in, OutputStream out) throws Exception {
		byte[] data = new byte[1024 * 1024];
		int index = 0;
		while ((index = in.read(data)) != -1) {
			out.write(data, 0, index);
		}
		in.close();
		out.close();
	}

	public static void main(String[] args) {
		String circleFenceURL = "http://yingyan.baidu.com/api/v3/fence/createcirclefence";
		String polygonFenceURL = "http://yingyan.baidu.com/api/v3/fence/createpolygonfence";
		//String params = "ak=KQAqxh1TMWjLu49WWjui95ap8vLjKscn&service_id=147386&fence_name=测试&monitored_person=#allentity&vertexes=\"116.301151,40.058674;116.314985,40.058343;116.314733,40.055581;116.300648,40.055581\"&coord_type=bd09ll";
		Map map = new HashMap();
		map.put("ak", "KQAqxh1TMWjLu49WWjui95ap8vLjKscn");
		map.put("service_id", "147386");
		map.put("fence_name", "ceshi001");
		map.put("monitored_person", "#allentity");
		
		/*map.put("longitude", "116.301151");
		map.put("latitude", "40.058674");
		map.put("radius", "500");*/
		
		map.put("vertexes", "40.058674,116.301151;40.058343,116.314985;40.055581,116.314733;40.055581,116.300648");
		map.put("coord_type", "bd09ll");
		try {
			String result = sendHttpRequestForm(polygonFenceURL, map);
			System.out.println(result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
